package fr.n7.khome.util;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import fr.n7.khome.core.Fuzzy;
import fr.n7.khome.model.Lodging;
import fr.n7.khome.model.LodgingType;
/**
 * This class allows to read a lodging file.
 * 
 * @author bbaccot && clej37
 *
 */
public class LodgingReader {

	/**
	 * Read a lodging file.
	 * 
	 * The input file must be as follows :
	 * - comment lines start with ## and are ignored.
	 * - other lines are composed of 6 fields, each field is 
	 * separated from the others by some '\t'. 
	 * 		_ field1 : price, as a readable fuzzy number
	 * 		_ field2 : type in {flat, house, other (seen as whatever)}
	 * 		_ field3 : live surface, as a readable fuzzy number
	 * 		_ field4 : field surface, as a readable fuzzy number
	 * 		_ field5 : age, as a readable fuzzy number
	 * 		_ field6 : work to realize, as a readable fuzzy number
	 * 
	 * @param filename - the name of the input file
	 * @return the list of lodgings in the input file, as Lodging object.
	 * @throws FuzzyFormatException 
	 * @throws InvalidFuzzyValueException 
	 */
	public static List<Lodging> read(String filename) throws FuzzyFormatException, InvalidFuzzyValueException {
		Logger logger = Logger.getLogger(LodgingReader.class);
		List<Lodging> result = new ArrayList<Lodging>();
		try {
			//Prepare to parse each line of the file
			String fuzzy = "([0-9\\p{Punct}]*)";
			String typ = "([a-zA-Z]*)";
			Pattern p = Pattern.compile(fuzzy+"\t+"+typ+"\t+"+fuzzy+"\t+"+fuzzy+"\t+"+fuzzy+"\t+"+fuzzy);
			//Open file (exceptions can be thrown but are caught above)
			BufferedReader file = new BufferedReader(new FileReader(filename));
			String line = file.readLine();
			while(line != null) {
				//A comment line
				if(!line.startsWith("##")) {
					Matcher m = p.matcher(line);
					//Yes ! It matches...
					if (m.matches()) {
						Fuzzy price = Fuzzy.parse(m.group(1));
						LodgingType type;
						if(m.group(2).equals("flat") || m.group(2).equals("FLAT")) {
							type = LodgingType.FLAT;
						} 
						else if (m.group(2).equals("house") || m.group(2).equals("HOUSE")) {
							type = LodgingType.HOUSE;
						}
						else {
							type = LodgingType.WHATEVER;
							logger.log(Level.WARN, m.group(2)+" was not understood. Assuming it is WHATEVER.");
						}
						Fuzzy liveSurface = Fuzzy.parse(m.group(3));
						Fuzzy fieldSurface = Fuzzy.parse(m.group(4));
						Fuzzy age = Fuzzy.parse(m.group(5));
						Fuzzy workPricePC = Fuzzy.parse(m.group(6));
						Lodging l = new Lodging(price,type,liveSurface,fieldSurface,age,workPricePC);
						result.add(l);
					}
					else {
						logger.log(Level.WARN, "\""+line+"\" was not understood and ignored.");
					}
				}
				line = file.readLine();
			}
		} catch (FileNotFoundException e) {
			logger.log(Level.ERROR, filename+
					" was not found, and consequently not read !");
		} catch (IOException e) {
			logger.log(Level.ERROR, filename+
					" is empty and cannot be read !");
		}   
		return result;
	}
	
	public static void main(String[] args) throws FuzzyFormatException, InvalidFuzzyValueException {
		List<Lodging> res = read("lodging.list");
		for(Lodging l : res ) {
			System.out.println(l);
			System.out.println("-------");
		}
		
	}
}

